/******************************************************************************* * Copyright (c) 2000, 2013 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.ui.tests.api; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IEditorReference; import org.eclipse.ui.IPartListener; import org.eclipse.ui.IPartListener2; import org.eclipse.ui.IPartService; import org.eclipse.ui.IPerspectiveDescriptor; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchPartReference; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.internal.SlavePartService; import org.eclipse.ui.part.FileEditorInput; import org.eclipse.ui.tests.harness.util.CallHistory; import org.eclipse.ui.tests.harness.util.EmptyPerspective; import org.eclipse.ui.tests.harness.util.FileUtil; import org.eclipse.ui.tests.harness.util.UITestCase; /** * Tests the IPartService, IPartListener and IPartListener2 interfaces. */ public class IPartServiceTest extends UITestCase { private IWorkbenchWindow fWindow; private IWorkbenchPage fPage; // Event state. private IWorkbenchPart eventPart; private IWorkbenchPartReference eventPartRef; class TestPartListener implements IPartListener { @Override public void partActivated(IWorkbenchPart part) { history.add("partActivated"); eventPart = part; } @Override public void partBroughtToTop(IWorkbenchPart part) { history.add("partBroughtToTop"); eventPart = part; } @Override public void partClosed(IWorkbenchPart part) { history.add("partClosed"); eventPart = part; } @Override public void partDeactivated(IWorkbenchPart part) { history.add("partDeactivated"); eventPart = part; } @Override public void partOpened(IWorkbenchPart part) { history.add("partOpened"); eventPart = part; } } class TestPartListener2 implements IPartListener2 { @Override public void partActivated(IWorkbenchPartReference ref) { history2.add("partActivated"); eventPartRef = ref; } @Override public void partBroughtToTop(IWorkbenchPartReference ref) { history2.add("partBroughtToTop"); eventPartRef = ref; } @Override public void partClosed(IWorkbenchPartReference ref) { history2.add("partClosed"); eventPartRef = ref; } @Override public void partDeactivated(IWorkbenchPartReference ref) { history2.add("partDeactivated"); eventPartRef = ref; } @Override public void partOpened(IWorkbenchPartReference ref) { history2.add("partOpened"); eventPartRef = ref; } @Override public void partHidden(IWorkbenchPartReference ref) { history2.add("partHidden"); eventPartRef = ref; } @Override public void partVisible(IWorkbenchPartReference ref) { history2.add("partVisible"); eventPartRef = ref; } @Override public void partInputChanged(IWorkbenchPartReference ref) { history2.add("partInputChanged"); eventPartRef = ref; } } private IPartListener partListener = new TestPartListener(); private IPartListener2 partListener2 = new TestPartListener2(); private CallHistory history = new CallHistory(partListener); private CallHistory history2 = new CallHistory(partListener2); public IPartServiceTest(String testName) { super(testName); } /** * Clear the event state. */ private void clearEventState() { eventPart = null; eventPartRef = null; history.clear(); history2.clear(); } @Override protected void doSetUp() throws Exception { super.doSetUp(); fWindow = openTestWindow(); fPage = fWindow.getActivePage(); } private IWorkbenchPartReference getRef(IWorkbenchPart part) { return fPage.getReference(part); } /** * Tests the addPartListener method on IWorkbenchPage's part service. */ public void testAddPartListenerToPage() throws Throwable { // From Javadoc: "Adds the given listener for part lifecycle events. // Has no effect if an identical listener is already registered." fPage.addPartListener(partListener); fPage.addPartListener(partListener2); // Open a view. // Verify events are received. clearEventState(); MockViewPart view = (MockViewPart) fPage.showView(MockViewPart.ID); assertTrue(history.verifyOrder(new String[] { "partOpened", "partActivated" })); assertEquals(view, eventPart); assertTrue(history2.verifyOrder(new String[] { "partOpened", "partVisible", "partActivated" })); assertEquals(getRef(view), eventPartRef); // Hide the view // Verify events are received. clearEventState(); fPage.hideView(view); assertTrue(history.verifyOrder(new String[] { "partDeactivated", "partClosed" })); assertEquals(view, eventPart); assertTrue(history2.verifyOrder(new String[] { "partDeactivated", "partHidden", "partClosed" })); assertEquals(getRef(view), eventPartRef); fPage.removePartListener(partListener); fPage.removePartListener(partListener2); } public void testLocalPartService() throws Throwable { IPartService service = fWindow .getService(IPartService.class); MockViewPart view = (MockViewPart) fPage.showView(MockViewPart.ID); MockViewPart view2 = (MockViewPart) fPage.showView(MockViewPart.ID2); IPartService slaveService = view.getSite() .getService(IPartService.class); assertTrue(service != slaveService); assertNotNull(slaveService); assertNotNull(service); assertTrue(slaveService instanceof SlavePartService); // Add listener, should receive events slaveService.addPartListener(partListener); fPage.activate(view); assertTrue(history.verifyOrder(new String[] { "partDeactivated", "partActivated" })); // Remove listener, should not receive events slaveService.removePartListener(partListener); clearEventState(); fPage.activate(view2); assertTrue(history.isEmpty()); // Hide another view, should still receive events slaveService.addPartListener(partListener); clearEventState(); fPage.hideView(view2); assertTrue(history.verifyOrder(new String[] { "partDeactivated", "partActivated", "partClosed" })); // Hide view, listeners should be disposed fPage.hideView(view); clearEventState(); fPage.showView(MockViewPart.ID3); assertTrue(history.isEmpty()); } /** * Tests the addPartListener method on IWorkbenchWindow's part service. */ public void testAddPartListenerToWindow() throws Throwable { // From Javadoc: "Adds the given listener for part lifecycle events. // Has no effect if an identical listener is already registered." IPartService service = fWindow .getService(IPartService.class); service.addPartListener(partListener); service.addPartListener(partListener2); // Open a view. // Verify events are received. clearEventState(); MockViewPart view = (MockViewPart) fPage.showView(MockViewPart.ID); assertTrue(history.verifyOrder(new String[] { "partOpened", "partActivated" })); assertEquals(view, eventPart); assertTrue(history2.verifyOrder(new String[] { "partOpened", "partVisible", "partActivated" })); assertEquals(getRef(view), eventPartRef); // Hide the view // Verify events are received. clearEventState(); fPage.hideView(view); assertTrue(history.verifyOrder(new String[] { "partDeactivated", "partClosed" })); assertEquals(view, eventPart); assertTrue(history2.verifyOrder(new String[] { "partDeactivated", "partHidden", "partClosed" })); assertEquals(getRef(view), eventPartRef); service.removePartListener(partListener); service.removePartListener(partListener2); } /** * Tests the removePartListener method on IWorkbenchPage's part service. */ public void testRemovePartListenerFromPage() throws Throwable { // From Javadoc: "Removes the given part listener. // Has no affect if an identical listener is not registered." // Add and remove listener. fPage.addPartListener(partListener); fPage.addPartListener(partListener2); fPage.removePartListener(partListener); fPage.removePartListener(partListener2); // Open a view. // Verify no events are received. clearEventState(); fPage.showView(MockViewPart.ID); assertTrue(history.isEmpty()); assertTrue(history2.isEmpty()); } /** * Tests the removePartListener method on IWorkbenchWindow's part service. */ public void testRemovePartListenerFromWindow() throws Throwable { // From Javadoc: "Removes the given part listener. // Has no affect if an identical listener is not registered." // Add and remove listener. IPartService service = fWindow .getService(IPartService.class); service.addPartListener(partListener); service.addPartListener(partListener2); service.removePartListener(partListener); service.removePartListener(partListener2); // Open a view. // Verify no events are received. clearEventState(); fPage.showView(MockViewPart.ID); assertTrue(history.isEmpty()); assertTrue(history2.isEmpty()); } /** * Tests the partHidden method by closing a view when it is not shared with * another perspective. Includes regression test for: Bug 60039 [ViewMgmt] * (regression) IWorkbenchPage#findView returns non-null value after part * has been closed */ public void testPartHiddenWhenClosedAndUnshared() throws Throwable { IPartListener2 listener = new TestPartListener2() { @Override public void partHidden(IWorkbenchPartReference ref) { super.partHidden(ref); // ensure that the notification is for the view we closed assertEquals(MockViewPart.ID, ref.getId()); // ensure that the view cannot be found assertNull(fPage.findView(MockViewPart.ID)); } }; MockViewPart view = (MockViewPart) fPage.showView(MockViewPart.ID); fPage.addPartListener(listener); clearEventState(); fPage.hideView(view); assertTrue(history2.contains("partHidden")); assertEquals(getRef(view), eventPartRef); fPage.removePartListener(listener); } /** * Tests the partHidden method by closing a view when it is shared with another perspective. * Includes regression test for: * Bug 60039 [ViewMgmt] (regression) IWorkbenchPage#findView returns non-null value after part has been closed */ public void XXXtestPartHiddenWhenClosedAndShared() throws Throwable { IPartListener2 listener = new TestPartListener2() { @Override public void partHidden(IWorkbenchPartReference ref) { super.partHidden(ref); // ensure that the notification is for the view we closed assertEquals(MockViewPart.ID, ref.getId()); // ensure that the view cannot be found assertNull(fPage.findView(MockViewPart.ID)); } }; MockViewPart view = (MockViewPart) fPage.showView(MockViewPart.ID); IPerspectiveDescriptor emptyPerspDesc2 = fWindow.getWorkbench() .getPerspectiveRegistry().findPerspectiveWithId( EmptyPerspective.PERSP_ID2); fPage.setPerspective(emptyPerspDesc2); MockViewPart view2 = (MockViewPart) fPage.showView(MockViewPart.ID); assertTrue(view == view2); fPage.addPartListener(listener); clearEventState(); fPage.hideView(view); assertTrue(history2.contains("partHidden")); assertEquals(getRef(view), eventPartRef); fPage.removePartListener(listener); } /** * Tests the partHidden method by activating another view in the same folder. */ public void testPartHiddenWhenObscured() throws Throwable { final boolean[] eventReceived = { false }; IPartListener2 listener = new TestPartListener2() { @Override public void partHidden(IWorkbenchPartReference ref) { super.partHidden(ref); // ensure that the notification is for the view that was obscured assertEquals(MockViewPart.ID, ref.getId()); // ensure that the view can still be found assertNotNull(fPage.findView(MockViewPart.ID)); eventReceived[0] = true; } }; MockViewPart view2 = (MockViewPart) fPage.showView(MockViewPart.ID2); MockViewPart view = (MockViewPart) fPage.showView(MockViewPart.ID); assertEquals(view, fPage.getActivePart()); fPage.addPartListener(listener); clearEventState(); fPage.activate(view2); fPage.removePartListener(listener); assertTrue(eventReceived[0]); } /** * Tests the partVisible method by showing a view when it is not * open in any other perspectives. */ public void testPartVisibleWhenOpenedUnshared() throws Throwable { final boolean[] eventReceived = { false }; IPartListener2 listener = new TestPartListener2() { @Override public void partVisible(IWorkbenchPartReference ref) { super.partVisible(ref); // ensure that the notification is for the view we opened assertEquals(MockViewPart.ID, ref.getId()); // ensure that the view can be found assertNotNull(fPage.findView(MockViewPart.ID)); eventReceived[0] = true; } }; fPage.addPartListener(listener); clearEventState(); MockViewPart view = (MockViewPart) fPage.showView(MockViewPart.ID); fPage.removePartListener(listener); assertEquals(view, fPage.getActivePart()); assertTrue(eventReceived[0]); } /** * Tests the partVisible method by showing a view when it is already * open in another perspective. */ public void testPartVisibleWhenOpenedShared() throws Throwable { final boolean[] eventReceived = { false }; IPartListener2 listener = new TestPartListener2() { @Override public void partVisible(IWorkbenchPartReference ref) { super.partVisible(ref); // ensure that the notification is for the view we opened assertEquals(MockViewPart.ID, ref.getId()); // ensure that the view can be found assertNotNull(fPage.findView(MockViewPart.ID)); eventReceived[0] = true; } }; MockViewPart view = (MockViewPart) fPage.showView(MockViewPart.ID); IPerspectiveDescriptor emptyPerspDesc2 = fWindow.getWorkbench() .getPerspectiveRegistry().findPerspectiveWithId( EmptyPerspective.PERSP_ID2); fPage.setPerspective(emptyPerspDesc2); fPage.addPartListener(listener); clearEventState(); MockViewPart view2 = (MockViewPart) fPage.showView(MockViewPart.ID); assertTrue(view == view2); assertEquals(view2, fPage.getActivePart()); assertTrue(eventReceived[0]); fPage.removePartListener(listener); } /** * Tests that both a part hidden and a part closed event are sent when * a part is closed * * @throws Throwable */ public void testPartHiddenBeforeClosing() throws Throwable { final boolean[] eventReceived = {false, false}; IPartListener2 listener = new TestPartListener2() { @Override public void partHidden(IWorkbenchPartReference ref) { super.partHidden(ref); // ensure that the notification is for the view we revealed assertEquals(MockViewPart.ID, ref.getId()); // ensure that the part cannot be found in the page assertNull(fPage.findView(MockViewPart.ID)); // Ensure that partHidden is sent first eventReceived[0] = true; assertFalse(eventReceived[1]); } @Override public void partClosed(IWorkbenchPartReference ref) { super.partClosed(ref); // ensure that the notification is for the view we revealed assertEquals(MockViewPart.ID, ref.getId()); // ensure that the view can no longer be found assertNull(fPage.findView(MockViewPart.ID)); // Ensure that partHidden is sent first eventReceived[1] = true; assertTrue(eventReceived[0]); } }; MockViewPart view = (MockViewPart) fPage.showView(MockViewPart.ID); assertEquals(view, fPage.getActivePart()); fPage.addPartListener(listener); clearEventState(); fPage.hideView(view); fPage.removePartListener(listener); history.verifyOrder(new String[] {"partHidden", "partClosed"}); assertTrue(eventReceived[0]); assertTrue(eventReceived[1]); } /** * Tests the partVisible method by activating a view obscured by * another view in the same folder. */ public void testPartVisibleWhenObscured() throws Throwable { final boolean[] eventReceived = { false }; IPartListener2 listener = new TestPartListener2() { @Override public void partVisible(IWorkbenchPartReference ref) { super.partVisible(ref); // ensure that the notification is for the view we revealed assertEquals(MockViewPart.ID, ref.getId()); // ensure that the view can still be found assertNotNull(fPage.findView(MockViewPart.ID)); eventReceived[0] = true; } }; MockViewPart view = (MockViewPart) fPage.showView(MockViewPart.ID); MockViewPart view2 = (MockViewPart) fPage.showView(MockViewPart.ID2); assertEquals(view2, fPage.getActivePart()); fPage.addPartListener(listener); clearEventState(); fPage.activate(view); fPage.removePartListener(listener); assertTrue(eventReceived[0]); } // /** // * Tests that when a partOpened is received for a view being shown, // * the view is available via findView, findViewReference, getViews and getViewReferences. // * // * @since 3.1 // */ // This does not work as expected. See bug 93784. // // public void testViewFoundWhenOpened() throws Throwable { // final String viewId = MockViewPart.ID; // final boolean[] eventReceived = { false, false }; // IPartListener listener = new TestPartListener() { // public void partOpened(IWorkbenchPart part) { // super.partOpened(part); // // ensure that the notification is for the view we opened // assertEquals(viewId, part.getSite().getId()); // // ensure that the view can be found // assertNotNull(fPage.findView(viewId)); // IViewPart[] views = fPage.getViews(); // assertEquals(1, views.length); // assertEquals(viewId, views[0].getSite().getId()); // eventReceived[0] = true; // } // }; // IPartListener2 listener2 = new TestPartListener2() { // public void partOpened(IWorkbenchPartReference ref) { // super.partOpened(ref); // // ensure that the notification is for the view we opened // assertEquals(viewId, ref.getId()); // // ensure that the view can be found // assertNotNull(fPage.findViewReference(viewId)); // IViewReference[] refs = fPage.getViewReferences(); // assertEquals(1, refs.length); // assertEquals(viewId, refs[0].getId()); // eventReceived[1] = true; // } // }; // fPage.addPartListener(listener); // fPage.addPartListener(listener2); // fPage.showView(viewId); // fPage.removePartListener(listener); // fPage.removePartListener(listener2); // assertTrue(eventReceived[0]); // assertTrue(eventReceived[1]); // } /** * Tests that when a partOpened is received for an editor being opened, * the editor is available via findEditor, getEditors, and getEditorReferences. * * @since 3.1 */ public void testEditorFoundWhenOpened() throws Throwable { final String editorId = MockEditorPart.ID1; IProject proj = FileUtil.createProject("IPartServiceTest"); IFile file = FileUtil.createFile("testEditorFoundWhenOpened.txt", proj); final IEditorInput editorInput = new FileEditorInput(file); final boolean[] eventReceived = { false, false }; IPartListener listener = new TestPartListener() { @Override public void partOpened(IWorkbenchPart part) { super.partOpened(part); // ensure that the notification is for the editor we opened assertEquals(editorId, part.getSite().getId()); // ensure that the editor can be found assertNotNull(fPage.findEditor(editorInput)); IEditorPart[] editors = fPage.getEditors(); assertEquals(1, editors.length); assertEquals(editorId, editors[0].getSite().getId()); eventReceived[0] = true; } }; IPartListener2 listener2 = new TestPartListener2() { @Override public void partOpened(IWorkbenchPartReference ref) { super.partOpened(ref); // ensure that the notification is for the editor we opened assertEquals(editorId, ref.getId()); // ensure that the editor can be found IEditorReference[] refs = fPage.getEditorReferences(); assertEquals(1, refs.length); assertEquals(editorId, refs[0].getId()); eventReceived[1] = true; } }; fPage.addPartListener(listener); fPage.addPartListener(listener2); fPage.openEditor(editorInput, editorId); fPage.removePartListener(listener); fPage.removePartListener(listener2); assertTrue(eventReceived[0]); assertTrue(eventReceived[1]); } }